import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:image_cropper/image_cropper.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';

class ImagePickerWidget extends StatefulWidget {
  final Function(List<File>) onImagesSelected;
  final String? label;
  final int crossAxisCount; // How many items per row (approx)
  final double spacing; // Spacing between items

  const ImagePickerWidget({
    super.key,
    required this.onImagesSelected,
    this.label = '上传图片',
    this.crossAxisCount = 3, // Default to 3 items per row
    this.spacing = 8.0, // Default spacing
  });

  @override
  ImagePickerWidgetState createState() => ImagePickerWidgetState();
}

class ImagePickerWidgetState extends State<ImagePickerWidget> {
  final List<File> _selectedImages = [];
  final ImagePicker _picker = ImagePicker();
  final FocusNode _focusNode = FocusNode();
  bool _isFocused = false;

  // Calculate item size based on crossAxisCount and spacing
  double _getItemSize(BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;
    // Estimate available width (considering padding)
    // This might need adjustment based on your parent layout
    final availableWidth =
        screenWidth -
        (widget.spacing * (widget.crossAxisCount + 1)) -
        40; // Subtract rough padding/margins
    return (availableWidth / widget.crossAxisCount).clamp(
      60.0,
      100.0,
    ); // Clamp size for reasonable min/max
  }

  @override
  void initState() {
    super.initState();
    _focusNode.addListener(() {
      if (mounted) {
        // Ensure the widget is still in the tree
        setState(() {
          _isFocused = _focusNode.hasFocus;
        });
      }
    });
  }

  @override
  void dispose() {
    _focusNode.removeListener(_onFocusChange); // Clean up listener
    _focusNode.dispose();
    super.dispose();
  }

  // Separate listener function for clarity and safe removal
  void _onFocusChange() {
    if (mounted) {
      setState(() {
        _isFocused = _focusNode.hasFocus;
      });
    }
  }

  Future<void> _pickImage(ImageSource source) async {
    // Close keyboard if open
    FocusScope.of(context).unfocus();
    // Request focus for the widget itself to trigger label animation
    _focusNode.requestFocus();

    if (source == ImageSource.gallery) {
      final List<XFile> pickedFiles = await _picker.pickMultiImage(
        imageQuality: 100, // Compress later
      );
      if (pickedFiles.isNotEmpty && mounted) {
        // Check mounted after await
        for (var pickedFile in pickedFiles) {
          await _processImage(File(pickedFile.path));
          if (!mounted) return; // Check again after async gap
        }
      }
    } else {
      final XFile? pickedFile = await _picker.pickImage(
        source: ImageSource.camera,
        imageQuality: 100, // Compress later
      );
      if (pickedFile != null && mounted) {
        // Check mounted after await
        await _processImage(File(pickedFile.path));
      }
    }
  }

  Future<void> _processImage(File imageFile) async {
    if (!mounted) return; // Check if widget is still mounted

    final CroppedFile? croppedFile = await ImageCropper().cropImage(
      sourcePath: imageFile.path,
      uiSettings: [
        AndroidUiSettings(
          toolbarTitle: '裁剪图片',
          toolbarColor: Theme.of(context).colorScheme.primary,
          toolbarWidgetColor: Theme.of(context).colorScheme.onPrimary,
          initAspectRatio: CropAspectRatioPreset.original,
          lockAspectRatio: false,
          aspectRatioPresets: [
            CropAspectRatioPreset.square,
            CropAspectRatioPreset.ratio3x2,
            CropAspectRatioPreset.original,
            CropAspectRatioPreset.ratio4x3,
            CropAspectRatioPreset.ratio16x9,
          ],
        ),
        IOSUiSettings(
          title: '裁剪图片',
          aspectRatioPresets: [
            CropAspectRatioPreset.square,
            CropAspectRatioPreset.ratio3x2,
            CropAspectRatioPreset.original,
            CropAspectRatioPreset.ratio4x3,
            CropAspectRatioPreset.ratio16x9,
          ],
        ),
      ],
    );

    if (croppedFile != null && mounted) {
      // Check mounted after await
      final File compressedFile = await _compressImage(File(croppedFile.path));
      if (!mounted) return; // Check again after async gap

      setState(() {
        _selectedImages.add(compressedFile);
      });
      widget.onImagesSelected(_selectedImages);
    }
  }

  Future<File> _compressImage(File file) async {
    // Create a unique path in the temporary directory
    final Directory tempDir = await Directory.systemTemp.createTemp();
    final String targetPath =
        '${tempDir.path}/compressed_${DateTime.now().millisecondsSinceEpoch}.jpg';

    try {
      final XFile? compressedXFile =
          await FlutterImageCompress.compressAndGetFile(
            file.absolute.path,
            targetPath,
            quality: 85, // Good balance of quality and size
            minWidth: 1024, // Set reasonable minimum dimensions
            minHeight: 1024,
            format: CompressFormat.jpeg, // Explicitly use JPEG
          );
      return compressedXFile != null ? File(compressedXFile.path) : file;
    } catch (e) {
      print("Image compression error: $e");
      // Fallback to the original file if compression fails
      return file;
    } finally {
      // Optionally clean up the original temp file if needed,
      // but compressedXFile uses a *new* path (targetPath)
    }
  }

  void _removeImage(int index) {
    if (mounted) {
      setState(() {
        _selectedImages.removeAt(index);
      });
      widget.onImagesSelected(_selectedImages);
      // Optional: If removing the last image, maybe unfocus?
      // if (_selectedImages.isEmpty) {
      //   _focusNode.unfocus();
      // }
    }
  }

  void _showPickerOptions(BuildContext context) {
    // Ensure focus when opening options
    _focusNode.requestFocus();
    showModalBottomSheet(
      context: context,
      builder:
          (context) => SafeArea(
            child: Wrap(
              // Use Wrap for content that might overflow vertically
              children: [
                ListTile(
                  leading: Icon(
                    Icons.photo_library, // Changed icon
                    color: Theme.of(context).colorScheme.primary,
                  ),
                  title: Text(
                    '从相册选择',
                    style: Theme.of(context).textTheme.bodyLarge,
                  ),
                  onTap: () {
                    Navigator.pop(context); // Close bottom sheet first
                    _pickImage(ImageSource.gallery);
                  },
                ),
                const Divider(height: 1, indent: 16, endIndent: 16),
                // Use Divider with indent
                ListTile(
                  leading: Icon(
                    Icons.camera_alt,
                    color: Theme.of(context).colorScheme.primary,
                  ),
                  title: Text(
                    '拍照',
                    style: Theme.of(context).textTheme.bodyLarge,
                  ),
                  onTap: () {
                    Navigator.pop(context); // Close bottom sheet first
                    _pickImage(ImageSource.camera);
                  },
                ),
              ],
            ),
          ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final bool showLabelAsHint = !_isFocused && _selectedImages.isEmpty;
    final double itemSize = _getItemSize(context); // Calculate item size

    return GestureDetector(
      onTap: () {
        if (!_focusNode.hasFocus) {
          _focusNode.requestFocus();
        }
      },
      child: LayoutBuilder(
        builder: (context, constraints) {
          // Calculate available width after accounting for InputDecorator padding
          final double paddingHorizontal =
              16.0 + widget.spacing; // left: 16.0, right: widget.spacing
          final double availableWidth =
              constraints.maxWidth - paddingHorizontal;

          return InputDecorator(
            isFocused: _isFocused,
            isEmpty: _selectedImages.isEmpty,
            decoration: InputDecoration(
              labelText: widget.label,
              floatingLabelStyle:
                  Theme.of(context)
                      .inputDecorationTheme
                      .floatingLabelStyle // Use global floating label style
                      ??
                  TextStyle(color: Theme.of(context).colorScheme.primary),
              floatingLabelBehavior:
                  _selectedImages.isEmpty
                      ? FloatingLabelBehavior.never
                      : FloatingLabelBehavior.auto,
              alignLabelWithHint: false,
              enabledBorder: OutlineInputBorder(
                borderRadius: BorderRadius.circular(8.0),
                borderSide: BorderSide(
                  color: Theme.of(context).colorScheme.outline,
                  width: 1.0,
                ),
              ),
              focusedBorder: OutlineInputBorder(
                borderRadius: BorderRadius.circular(8.0),
                borderSide: BorderSide(
                  color: Theme.of(context).colorScheme.primary,
                  width: 2.0,
                ),
              ),
              contentPadding: EdgeInsets.only(
                left: 16.0,
                top: widget.spacing + (showLabelAsHint ? 12 : 18),
                right: widget.spacing,
                bottom: widget.spacing,
              ),
              filled: true,
              fillColor: Theme.of(context).colorScheme.surface,
            ),
            child: Padding(
              padding: EdgeInsets.zero,
              child:
                  _selectedImages.isEmpty
                      ? Row(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          // Label placeholder (1/3 width)
                          if (widget.label != null)
                            SizedBox(
                              width: availableWidth * (1 / 3),
                              height:
                                  itemSize, // Match item size for consistency
                            ),
                          // "+" button (left-aligned in 2/3 width)
                          SizedBox(
                            width: availableWidth * (2 / 3),
                            child: Align(
                              alignment: Alignment.centerLeft,
                              child: _buildAddButton(itemSize),
                            ),
                          ),
                        ],
                      )
                      : Wrap(
                        spacing: widget.spacing,
                        runSpacing: widget.spacing,
                        crossAxisAlignment: WrapCrossAlignment.center,
                        alignment: WrapAlignment.start,
                        children: [
                          ..._selectedImages.asMap().entries.map((entry) {
                            int index = entry.key;
                            File image = entry.value;
                            return _buildImagePreview(image, index, itemSize);
                          }),
                          _buildAddButton(itemSize),
                        ],
                      ),
            ),
          );
        },
      ),
    );
  }

  // Helper Widget for Image Preview
  Widget _buildImagePreview(File image, int index, double itemSize) {
    return SizedBox(
      width: itemSize,
      height: itemSize,
      child: Stack(
        children: [
          Positioned.fill(
            child: Card(
              // Use Card for elevation/border look
              elevation: 1,
              margin: EdgeInsets.zero,
              // Remove card margin
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(4.0),
                // Smaller radius for items
                side: BorderSide(
                  color: Theme.of(context).colorScheme.outline.withOpacity(0.5),
                  width: 0.5,
                ),
              ),
              clipBehavior: Clip.antiAlias,
              // Clip the image
              child: Image.file(
                image,
                fit: BoxFit.cover,
                errorBuilder:
                    (context, error, stackTrace) =>
                        const Center(child: Icon(Icons.broken_image, size: 24)),
              ),
            ),
          ),
          Positioned(
            top: 2, // Adjust position
            right: 2, // Adjust position
            child: InkWell(
              // Use InkWell for better tap feedback
              onTap: () => _removeImage(index),
              radius: 12, // Smaller radius for tap area
              child: Container(
                padding: const EdgeInsets.all(2.0), // Padding inside circle
                decoration: BoxDecoration(
                  color: Theme.of(context).colorScheme.error.withOpacity(0.8),
                  shape: BoxShape.circle,
                ),
                child: Icon(
                  Icons.close,
                  size: 14, // Smaller icon
                  color: Theme.of(context).colorScheme.onError,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

  // Helper Widget for the Add Button
  Widget _buildAddButton(double itemSize) {
    return SizedBox(
      width: itemSize,
      height: itemSize,
      child: Material(
        // Use Material for InkWell effects
        color: Theme.of(
          context,
        ).colorScheme.surfaceVariant.withOpacity(0.5), // Subtle background
        borderRadius: BorderRadius.circular(4.0),
        child: InkWell(
          borderRadius: BorderRadius.circular(4.0),
          onTap: () => _showPickerOptions(context),
          child: Center(
            child: Icon(
              Icons.add_photo_alternate_outlined, // More descriptive icon
              size: itemSize * 0.4, // Relative icon size
              color: Theme.of(context).colorScheme.primary,
            ),
          ),
        ),
      ),
    );
  }
}
